from datetime import datetime
from typing import List, Dict, Any, Optional
from sqlalchemy.orm import Session
from sqlalchemy import func, desc
from loguru import logger

from ..db.models.user import User, Group, Friend
from ..db.models.chat import Room, Message as DBMessage, RoomMember
from ..services.message import MessageService

class ConversationService:
    @staticmethod
    def get_conversations(db: Session, user_id: int) -> List[Dict[str, Any]]:
        """获取用户的所有会话列表"""
        # 查找用户所在的所有房间
        room_members = db.query(RoomMember).filter(RoomMember.user_id == user_id).all()
        room_ids = [member.room_id for member in room_members]
        
        # 获取这些房间的详细信息
        rooms = db.query(Room).filter(Room.id.in_(room_ids) if room_ids else False).all()
        
        result = []
        for room in rooms:
            # 基本会话结构
            conversation = {
                "id": room.id,
                "roomId": room.id,
                "userId": user_id,
                "message": ConversationService.get_last_message(db, room.id),
                "friend": None,
                "group": None
            }
            
            # 根据房间类型设置friend或group
            if room.type == 0:  # 私聊
                # 找出私聊对象
                conversation["friend"] = ConversationService.get_friend_info(db, user_id, room.id)
            else:  # 群聊
                # 设置群组信息
                conversation["group"] = {
                    "id": room.id,
                    "name": room.name,
                    "avatar": room.avatar or ""
                }
            
            result.append(conversation)
        
        return result
    
    @staticmethod
    def get_last_message(db: Session, room_id: int) -> Dict[str, Any]:
        """获取房间的最后一条消息"""
        # 查询最后一条消息
        message = db.query(DBMessage).filter(
            DBMessage.room_id == room_id
        ).order_by(desc(DBMessage.created_at)).first()
        
        if not message:
            # 如果没有消息，返回空消息结构
            return {
                "id": 0,
                "type": 0,
                "text": "",
                "image": None,
                "audio": None,
                "file": None,
                "status": 1,
                "createdAt": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "userId": 0,
                "nickname": "",
                "avatar": None,
                "sex": 0,
                "email": None
            }
        
        # 获取发送者信息
        sender = db.query(User).filter(User.id == message.sender_id).first()
        
        # 构建消息结构
        message_data = {
            "id": message.id,
            "type": int(message.type) if message.type and message.type.isdigit() else 0,
            "text": message.content if message.type == "0" else None,
            "image": message.file_path if message.type == "1" else None,
            "audio": message.file_path if message.type == "2" else None,
            "file": message.file_path if message.type == "3" else None,
            "status": message.status,
            "createdAt": message.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "userId": sender.id if sender else 0,
            "nickname": sender.nickname if sender else "",
            "avatar": sender.avatar if sender else None,
            "sex": sender.sex if sender else 0,
            "email": sender.email if sender else None
        }
        
        return message_data
    
    @staticmethod
    def get_friend_info(db: Session, user_id: int, room_id: int) -> Dict[str, Any]:
        """获取私聊对象的信息"""
        # 查找房间中的另一个用户
        other_member = db.query(RoomMember).filter(
            RoomMember.room_id == room_id,
            RoomMember.user_id != user_id
        ).first()
        
        if not other_member:
            return None
        
        # 获取对方用户信息
        other_user = db.query(User).filter(User.id == other_member.user_id).first()
        
        if not other_user:
            return None
        
        # 查找好友关系
        friend = db.query(Friend).filter(
            Friend.user_id == user_id,
            Friend.friend_id == other_user.id
        ).first()
        
        # 构建好友信息
        friend_info = {
            "id": friend.id if friend else 0,
            "remark": friend.remark if friend else None,
            "userId": other_user.id,
            "nickname": other_user.nickname,
            "avatar": other_user.avatar,
            "sex": other_user.sex,
            "online": 1 if other_user.online else 0,
            "email": other_user.email,
            "last_at": other_user.last_at.strftime("%Y-%m-%d %H:%M:%S") if other_user.last_at else None,
            "created_at": other_user.created_at.strftime("%Y-%m-%d %H:%M:%S") if other_user.created_at else None
        }
        
        return friend_info
    
    @staticmethod
    def create_or_get_conversation(db: Session, user_id: int, target_id: int) -> Dict[str, Any]:
        """创建或获取与目标用户的会话"""
        # 检查是否已存在私聊房间
        existing_room = None
        
        try:
            logger.info(f"尝试创建或获取用户 {user_id} 和用户 {target_id} 之间的私聊会话")
            
            # 首先尝试直接查询是否存在包含这两个用户的私聊房间
            # 1. 获取所有包含用户1的房间
            user1_rooms = db.query(RoomMember.room_id).filter(RoomMember.user_id == user_id).all()
            user1_room_ids = [r.room_id for r in user1_rooms]
            logger.info(f"用户 {user_id} 所在的房间IDs: {user1_room_ids}")
            
            # 2. 从这些房间中查找也包含用户2的房间
            if user1_room_ids:  # 确保列表不为空
                # 查找用户2在哪些房间中
                user2_rooms_query = db.query(RoomMember.room_id).filter(
                    RoomMember.user_id == target_id,
                    RoomMember.room_id.in_(user1_room_ids)
                )
                user2_room_ids = [r.room_id for r in user2_rooms_query.all()]
                logger.info(f"用户 {target_id} 与用户 {user_id} 共同所在的房间IDs: {user2_room_ids}")
                
                # 3. 在共同的房间中查找类型为私聊的房间
                if user2_room_ids:
                    private_rooms = db.query(Room).filter(
                        Room.id.in_(user2_room_ids),
                        Room.type == 0  # 0表示私聊
                    ).all()
                    
                    if private_rooms:
                        # 找到了已存在的私聊房间
                        existing_room = private_rooms[0]
                        logger.info(f"找到已存在的私聊房间: {existing_room.id}")
            
            # 如果不存在，创建新房间
            if not existing_room:
                logger.info(f"未找到现有私聊房间，准备创建新房间")
                # 创建新的私聊房间
                new_room = Room(
                    name=f"私聊-{user_id}-{target_id}",
                    type=0,  # 私聊
                    creator_id=user_id,
                    created_at=datetime.now()
                )
                db.add(new_room)
                db.flush()  # 刷新以获取新房间ID
                logger.info(f"创建新的私聊房间: {new_room.id}")
                
                # 添加第一个用户作为创建者
                member1 = RoomMember(
                    room_id=new_room.id,
                    user_id=user_id,
                    role=2,  # 创建者
                    created_at=datetime.now()
                )
                db.add(member1)
                logger.info(f"添加用户 {user_id} 到房间 {new_room.id} 作为创建者")
                
                # 添加第二个用户作为普通成员
                member2 = RoomMember(
                    room_id=new_room.id,
                    user_id=target_id,
                    role=0,  # 普通成员
                    created_at=datetime.now()
                )
                db.add(member2)
                logger.info(f"添加用户 {target_id} 到房间 {new_room.id} 作为普通成员")
                
                # 提交事务
                db.commit()
                logger.info(f"提交事务，创建私聊房间完成")
                
                existing_room = new_room
            
            # 获取会话信息
            conversation = {
                "id": existing_room.id,
                "roomId": existing_room.id,
                "userId": user_id,
                "message": ConversationService.get_last_message(db, existing_room.id),
                "friend": ConversationService.get_friend_info(db, user_id, existing_room.id),
                "group": None
            }
            
            logger.info(f"返回会话信息，会话ID: {conversation['id']}")
            return conversation
            
        except Exception as e:
            # 发生错误时回滚事务
            db.rollback()
            logger.error(f"创建或获取私聊会话失败: {str(e)}")
            raise e